package org.sraosha.framework.manager;

import com.rabbitmq.client.*;
import lombok.extern.slf4j.Slf4j;
import java.io.IOException;
import java.util.concurrent.TimeoutException;

/**
 * @desc   Rabbitmq的管理类
 */
@Slf4j
public class RabbitMqManager {
    private static ConnectionFactory factory;
    private static Connection connection;
    private static Channel channel;

    public RabbitMqManager(String host, int port, String username, String password, String virtualHost) {
        factory = new ConnectionFactory();
        factory.setHost(host);
        factory.setPort(port);
        factory.setUsername(username);
        factory.setPassword(password);

        // 设置mq请求的心跳为15秒
        factory.setRequestedHeartbeat(15);
        factory.setAutomaticRecoveryEnabled(true);
        factory.setTopologyRecoveryEnabled(true);

        if (null != virtualHost) {
            factory.setVirtualHost(virtualHost);
        }

        try {
            connection = factory.newConnection();
            channel = connection.createChannel();
        } catch (IOException | TimeoutException e) {
            log.error("RabbitMqManager : 创建连接失败,e:", e);
            e.printStackTrace();
        }
    }

    /**
     * 关闭连接
     *
     * @throws IOException
     * @throws TimeoutException
     */
    public void close() throws IOException, TimeoutException {
        channel.close();
        connection.close();
    }

    /**
     * 获取channel
     *
     * @return 返回channel
     */
    public Channel getChannel() {
        return channel;
    }

    /**
     * 向指定交换机发送消息
     *
     * @param exchange        交换机名称
     * @param queueName       队列名称
     * @param basicProperties 基础配置信息，默认为null
     * @param b               消息二进制数据
     * @throws IOException 抛出IO异常
     */
    public void basicPublish(String exchange, String queueName, AMQP.BasicProperties basicProperties, byte[] b) throws IOException {
        channel.exchangeDeclare(exchange, BuiltinExchangeType.DIRECT, true);
        channel.basicPublish(exchange, queueName, basicProperties, b);
    }

    /**
     * 向指定交换机发送延迟消息(延迟消息类型不一致)
     *
     * @param exchange        交换机名称
     * @param basicProperties 基础配置信息，默认为null
     * @param b               消息二进制数据
     * @throws IOException 抛出IO异常
     */
    public void basicPublishDelay(String exchange, String routingKey, AMQP.BasicProperties basicProperties, byte[] b) throws IOException {
        channel.basicPublish(exchange, routingKey, basicProperties, b);
    }

    /**
     * 向指定交换机发送消息
     *
     * @param exchange        交换机名称
     * @param queueName       队列名称
     * @param routingKey      路由Key
     * @param basicProperties 基础配置信息，默认为null
     * @param b               消息二进制数据
     * @throws IOException 抛出IO异常
     */
    public void basicPublish(String exchange, String queueName, String routingKey, AMQP.BasicProperties basicProperties, byte[] b) throws IOException {
        channel.queueBind(queueName, exchange, routingKey);
        channel.exchangeDeclare(exchange, BuiltinExchangeType.DIRECT, true);
        channel.basicPublish(exchange, routingKey, basicProperties, b);
    }
}